package org.jeecg.modules.system.aspect;

import javax.servlet.http.HttpServletRequest;

import com.google.common.cache.Cache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.PreventRepeatSubmit;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.concurrent.TimeUnit;

/**
 * @author jiangxz
 * @description 防重复提交AOP
 * @date 2020-10-27
 */
@Aspect
@Component
public class PreventRepeatSubmitAspect {

    private Log logger = LogFactory.getLog(getClass());

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Around("execution(* org.jeecg.modules..*Controller.*(..)) && @annotation(nrs)")
    public Object arround(ProceedingJoinPoint pjp, PreventRepeatSubmit nrs) throws Throwable {
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = TokenUtils.getTokenByRequest(request);
        String key = token + "-" + request.getServletPath();
        if (opsForValue.get(key) == null) {// 如果缓存中有这个url视为重复提交
            Object o = pjp.proceed();
            opsForValue.set(key, 0, nrs.value(), TimeUnit.SECONDS);// 5秒后释放
            return o;
        } else {
            logger.error("重复提交！");
            return Result.error("请勿短时间内重复点击按钮！");
        }
    }
}
